/*
 *    Copyright (C) 2017 MINDORKS NEXTGEN PRIVATE LIMITED
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.prdownloader.database;


import ohos.app.Context;
import ohos.data.DatabaseHelper;
import ohos.data.dataability.DataAbilityPredicates;
import ohos.data.dataability.DataAbilityUtils;
import ohos.data.rdb.RdbOpenCallback;
import ohos.data.rdb.RdbPredicates;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.StoreConfig;
import ohos.data.rdb.ValuesBucket;
import ohos.data.resultset.ResultSet;

import java.util.ArrayList;
import java.util.List;

/**
 * app数据库支持
 *
 * @author amitshekhar
 * @since 2017-11-17
 */

public class AppDbHelper implements DbHelper {

    /**
     * 数据库表名
     */
    public static final String TABLE_NAME = "prdownloader";

    private static final String DATABASE_NAME = "prdownloader.db";
    private static final int DATABASE_VERSION = 1;
    /*  创建关系型数据库 */
    private StoreConfig config = StoreConfig.newDefaultConfig(DATABASE_NAME);
    private RdbStore db;

    private RdbOpenCallback rdbOpenCallback = new RdbOpenCallback() {
        @Override
        public void onCreate(RdbStore store) {
            store.executeSql("CREATE TABLE IF NOT EXISTS "
                +
                AppDbHelper.TABLE_NAME + "( "
                +
                DownloadModel.ID + " INTEGER PRIMARY KEY, "
                +
                DownloadModel.URL + " VARCHAR, "
                +
                DownloadModel.ETAG + " VARCHAR, "
                +
                DownloadModel.DIR_PATH + " VARCHAR, "
                +
                DownloadModel.FILE_NAME + " VARCHAR, "
                +
                DownloadModel.TOTAL_BYTES + " INTEGER, "
                +
                DownloadModel.DOWNLOADED_BYTES + " INTEGER, "
                +
                DownloadModel.LAST_MODIFIED_AT + " INTEGER "
                +
                ")");
        }

        @Override
        public void onUpgrade(RdbStore store, int oldVersion, int newVersion) {
        }
    };


    public AppDbHelper(Context context) {
        DatabaseHelper databaseHelper = new DatabaseHelper(context);
        db = databaseHelper.getRdbStore(config, DATABASE_VERSION, rdbOpenCallback, null);
    }

    @Override
    public RdbStore getDb() {
        return db;
    }

    @Override
    public DownloadModel find(int id) {
        ResultSet cursor = null;
        DownloadModel model = null;
        try {
            cursor = db.querySql("SELECT * FROM " + TABLE_NAME + " WHERE "
                +
                DownloadModel.ID + " = " + id, null);
            if (cursor != null && cursor.goToFirstRow()) {
                model = new DownloadModel();
                model.setId(id);
                model.setUrl(cursor.getString(cursor.getColumnIndexForName(DownloadModel.URL)));
                model.setETag(cursor.getString(cursor.getColumnIndexForName(DownloadModel.ETAG)));
                model.setDirPath(cursor.getString(cursor.getColumnIndexForName(DownloadModel.DIR_PATH)));
                model.setFileName(cursor.getString(cursor.getColumnIndexForName(DownloadModel.FILE_NAME)));
                model.setTotalBytes(cursor.getLong(cursor.getColumnIndexForName(DownloadModel.TOTAL_BYTES)));
                model.setDownloadedBytes(cursor.getLong(cursor.getColumnIndexForName(DownloadModel.DOWNLOADED_BYTES)));
                model.setLastModifiedAt(cursor.getLong(cursor.getColumnIndexForName(DownloadModel.LAST_MODIFIED_AT)));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return model;
    }

    @Override
    public void insert(DownloadModel model) {

        ValuesBucket values = new ValuesBucket();
        values.putInteger(DownloadModel.ID, model.getId());

        values.putString(DownloadModel.URL, model.getUrl());
        values.putString(DownloadModel.ETAG, model.getETag());
        values.putString(DownloadModel.DIR_PATH, model.getDirPath());
        values.putString(DownloadModel.FILE_NAME, model.getFileName());
        values.putLong(DownloadModel.TOTAL_BYTES, model.getTotalBytes());
        values.putLong(DownloadModel.DOWNLOADED_BYTES, model.getDownloadedBytes());
        values.putLong(DownloadModel.LAST_MODIFIED_AT, model.getLastModifiedAt());
        db.insert(TABLE_NAME, values);

    }

    @Override
    public void update(DownloadModel model) {

        ValuesBucket values = new ValuesBucket();
        values.putString(DownloadModel.URL, model.getUrl());
        values.putString(DownloadModel.ETAG, model.getETag());
        values.putString(DownloadModel.DIR_PATH, model.getDirPath());
        values.putString(DownloadModel.FILE_NAME, model.getFileName());
        values.putLong(DownloadModel.TOTAL_BYTES, model.getTotalBytes());
        values.putLong(DownloadModel.DOWNLOADED_BYTES, model.getDownloadedBytes());
        values.putLong(DownloadModel.LAST_MODIFIED_AT, model.getLastModifiedAt());

        DataAbilityPredicates predicates = new DataAbilityPredicates()
            .equalTo(DownloadModel.ID, String.valueOf(model.getId()));
        RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(predicates, TABLE_NAME);
        db.update(values, rdbPredicates);

    }

    @Override
    public void updateProgress(int id, long downloadedBytes, long lastModifiedAt) {

        ValuesBucket values = new ValuesBucket();
        values.putLong(DownloadModel.DOWNLOADED_BYTES, downloadedBytes);
        values.putLong(DownloadModel.LAST_MODIFIED_AT, lastModifiedAt);
        DataAbilityPredicates predicates = new DataAbilityPredicates()
            .equalTo(DownloadModel.ID, String.valueOf(id));
        RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(predicates, TABLE_NAME);
        db.update(values, rdbPredicates
        );

    }

    @Override
    public void remove(int id) {
        db.executeSql("DELETE FROM " + TABLE_NAME + " WHERE "
            +
            DownloadModel.ID + " = " + id);
    }

    @Override
    public List<DownloadModel> getUnwantedModels(int days) {
        List<DownloadModel> models = new ArrayList<>();
        ResultSet cursor = null;
        try {
            final long daysInMillis = (long) days * 24 * 60 * 60 * 1000L;
            final long beforeTimeInMillis = System.currentTimeMillis() - daysInMillis;
            cursor = db.querySql("SELECT * FROM " + TABLE_NAME + " WHERE "
                +
                DownloadModel.LAST_MODIFIED_AT + " <= " + beforeTimeInMillis, null);
            if (cursor != null && cursor.goToFirstRow()) {
                do {
                    DownloadModel model = new DownloadModel();
                    model.setId(cursor.getInt(cursor.getColumnIndexForName(DownloadModel.ID)));
                    model.setUrl(cursor.getString(cursor.getColumnIndexForName(DownloadModel.URL)));
                    model.setETag(cursor.getString(cursor.getColumnIndexForName(DownloadModel.ETAG)));
                    model.setDirPath(cursor.getString(cursor.getColumnIndexForName(DownloadModel.DIR_PATH)));
                    model.setFileName(cursor.getString(cursor.getColumnIndexForName(DownloadModel.FILE_NAME)));
                    model.setTotalBytes(cursor.getLong(cursor.getColumnIndexForName(DownloadModel.TOTAL_BYTES)));
                    model.setDownloadedBytes(cursor.getLong(cursor.getColumnIndexForName(DownloadModel.DOWNLOADED_BYTES)));
                    model.setLastModifiedAt(cursor.getLong(cursor.getColumnIndexForName(DownloadModel.LAST_MODIFIED_AT)));
                    models.add(model);
                } while (cursor.goToNextRow());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return models;
    }

    @Override
    public void clear() {
        RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(null, TABLE_NAME);
        db.delete(rdbPredicates);
    }
}
